package com.xhh.microfin.dispatch.service.impl;

import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader;
import com.xhh.microfin.dispatch.common.utils.DateTimeUtil;
import com.xhh.microfin.dispatch.exception.OrderExistException;
import com.xhh.microfin.dispatch.model.consts.ProcessConsts;
import com.xhh.microfin.dispatch.model.entity.Order;
import com.xhh.microfin.dispatch.model.entity.ProcessInstance;
import com.xhh.microfin.dispatch.model.entity.Task;
import com.xhh.microfin.dispatch.model.mapper.OrderMapper;
import com.xhh.microfin.dispatch.model.mapper.extend.OrderExtendMapper;
import com.xhh.microfin.dispatch.model.vo.OrderVo;
import com.xhh.microfin.dispatch.service.OrderService;
import com.xhh.microfin.dispatch.service.process.IProcess;
import com.xhh.microfin.dispatch.service.process.impl.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Author: 003035
 * @Date: 2019/1/16
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private IProcess process;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderExtendMapper orderExtendMapper;

    @Override
    public String getProcessCode(OrderVo orderVo) {
        return "test"; // TODO: 2019/1/16
    }

    @Override
    public void add(OrderVo orderVo) {
        // save order
        Order orderOrigin = orderExtendMapper.selectByOrderSn(orderVo.getOrderSn());
        if (null != orderOrigin) {
            throw new OrderExistException();
        }

        orderMapper.insert(convertOrderFromOrderVo(orderVo));

        ProcessInstance processInstance = process.startProcess(getProcessCode(orderVo),orderVo.getOrderSn());

        process.process(processInstance);
    }

    @Override
    public void process(String orderSn) {

        process.process(process.getProcessInstanceByBusId(orderSn));
    }

    @Override
    public boolean preCheck(String orderSn) {

        return new Random().nextBoolean();
    }

    @Override
    public void callBack(String orderSn, String taskCode,Integer status) {
        ProcessInstance processInstanceByBusId = process.getProcessInstanceByBusId(orderSn);
        List<Task> tasks = process.getTaskByProcessInstanceIdAndTaskCode(processInstanceByBusId.getId(), taskCode);
        tasks.forEach(task -> {
            process.addTaskVar(task, new Var(taskCode + ProcessConsts.DONE, ProcessConsts.DONE, DateTimeUtil.getNowSeconds()));
            if (1 == status.intValue()) {
                process.addTaskVar(task, new Var(ProcessConsts.TASK_SUCCESS, ProcessConsts.TRUE, DateTimeUtil.getNowSeconds()));
            } else {
                process.addTaskVar(task, new Var(ProcessConsts.TASK_SUCCESS, ProcessConsts.FALSE, DateTimeUtil.getNowSeconds()));
            }
        });
        process.process(processInstanceByBusId);
    }

    private Order convertOrderFromOrderVo(OrderVo orderVo) {

        Order order = new Order();
        order.setLoanAmount(orderVo.getLoanAmount());
        order.setOrderSn(orderVo.getOrderSn());
        order.setProductCode(orderVo.getProductCode());
        order.setUserId(orderVo.getUserId());
        return order;
    }
}
